package com.xgpro.common.dingtalk.controller;

import com.alibaba.fastjson.JSONObject;
import com.xgpro.common.controller.BaseController;
import com.xgpro.common.dingtalk.auth.AuthHelper;
import com.xgpro.common.dingtalk.service.contact.DDUserService;
import com.xgpro.common.enums.ResultCodeEnum;
import com.xgpro.common.exceptions.BusinessRuntimeException;
import com.xgpro.common.results.PageResult;
import com.xgpro.common.results.ResponseResult;
import com.xgpro.domain.rolemanage.dto.UserDTO;
import com.xgpro.domain.rolemanage.entity.*;
import com.xgpro.domain.studycentre.entity.Edu;
import com.xgpro.domain.talentintroduction.entity.User;
import com.xgpro.mapper.rolemanage.RoleMapper;
import com.xgpro.mapper.studycentre.EduMapper;
import com.xgpro.mapper.talentintroduction.UserMapper;
import com.xgpro.pc.rolemanage.service.DepartmentService;
import com.xgpro.pc.rolemanage.service.RoleService;
import com.xgpro.pc.rolemanage.service.TokenService;
import com.xgpro.pc.rolemanage.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * @program: xgpro__dev
 * @description: 钉钉用户免登
 * @author: likai
 * @create: 2019-10-09 23:57
 **/
@CrossOrigin(allowCredentials = "true")
@RestController
public class DDUserController extends BaseController {

    /**
     * 菜单权限
     */
    public static final String MENU_PER = "1";

    /**
     * 按钮权限
     */
    public static final String POINT_PER = "3";

    /**
     * TAB页权限
     */
    public static final String TAB_PER="2";

    @Resource
    private DDUserService ddUserService;

    @Resource
    private UserService userService;

    @Resource
    private DepartmentService departmentService;

    @Resource
    private EduMapper eduMapper;

    @Resource
    private RoleService roleService;

    @Resource
    private TokenService tokenService;

    @Value("${DD_ENV.APP_KEY}")
    private String APP_KEY;

    @Value("${DD_ENV.APP_SECRET}")
    private String APP_SECRET;

    @Resource
    private UserMapper userMapper;



    /**
     * 登录鉴权
     *
     * @param code
     * @param request
     * @return
     * @throws Exception
     */
    @GetMapping("/login")
    public ResponseResult login(@RequestParam("code") String code, HttpServletRequest request) throws Exception {
        System.out.println("====================================调用Login接口========================================");
        //1.获取session
        HttpSession httpSession = request.getSession();
        //2.获取token
        String accessToken = null;
        Token token = tokenService.findToken();
        String ticket = null;
        if(token.getDate()!=null&&token.getToken()!=null){
            if((new Date().getTime()-token.getDate().getTime())<=(105*60*1000)){
                accessToken=token.getToken();
            }else{
                accessToken = AuthHelper.getAccessToken(APP_KEY, APP_SECRET);
                if (null != accessToken){
                    ticket = AuthHelper.getJsapiTicket(accessToken);
                    System.out.println("--------ticket-------------"+ticket);
                }
//                tokenService.update(new Date(),accessToken,);
                tokenService.updateticket(new Date(),accessToken,ticket);
            }
        }else{
            accessToken = AuthHelper.getAccessToken(APP_KEY, APP_SECRET);
            if (null != accessToken){
                ticket = AuthHelper.getJsapiTicket(accessToken);
                System.out.println("--------ticket-------------"+ticket);
            }
//            tokenService.update(new Date(),accessToken);
            tokenService.updateticket(new Date(),accessToken,ticket);
        }

        logger.info("code:{},accessToken:{}", code, accessToken);
        //3.根据token和前端传过来的code获取用户的信息
        JSONObject jsonObject = ddUserService.getUserInfo(accessToken, code);
        //4.查询数据库进行登录校验
        Map<String, Object> param = new HashMap<>();
        param.put("userId", jsonObject.get("userid"));
        PageResult pageResult = userService.listUser(1, 1, param);
        List<UserDTO> rows = pageResult.getRows();
        System.out.println("返回的集合："+rows);
        //该用户可以登录微应用
        if (!CollectionUtils.isEmpty(rows)) {
            UserDTO user = rows.get(0);

            //用户id存入session
            httpSession.setAttribute("id", user.getId());
            //部门id存入session
            httpSession.setAttribute("deptId", user.getDeptId());
            //二级部门id存入session
            httpSession.setAttribute("secondDeptId",user.getSecondDeptId());
            Set<Role> roleListByUserId = userService.findRoleListByUserId(user.getId());
            List<Integer> roleIds = new ArrayList<>();

            if (!CollectionUtils.isEmpty(roleListByUserId)) {
                for (Role role : roleListByUserId) {
                    roleIds.add(role.getId());
                }
            }
            //角色id集合存入session
            httpSession.setAttribute("roleIds", roleIds);
            //设置session过期时间为8小时
            httpSession.setMaxInactiveInterval(60 *60);

            System.out.println("========================================打印Session开始====================================");
            String[] valueNames = httpSession.getValueNames();
            System.out.println("session中的个数:"+valueNames.length);
            for (String valueName : valueNames) {
                System.out.println("sessionId: "+valueName+"-----sessionValue: "+httpSession.getValue(valueName));
            }
            System.out.println("-----------------------------------------打印session结束 ------------------------------------");
            return ResponseResult.ok();
        } else {
            //用户不能登录微应用，则提示用户
            System.out.println("login 方法抛出的不能登录的异常");
            return ResponseResult.failure(ResultCodeEnum.CAN_NOT_LOGIN.getCode(), ResultCodeEnum.CAN_NOT_LOGIN.getMessage());
//            throw new BusinessRuntimeException();
        }
    }

    @RequestMapping("/getUserInfo")
    public ResponseResult getUserInfo(HttpServletRequest request) {
        System.out.println("调用了---> userInfo接口");
       //request.getSession().setAttribute("id",1);
        Object id = request.getSession().getAttribute("id");
        if (ObjectUtils.isEmpty(id)) {
            System.out.println("getUserInfo 方法抛出的不能登录的异常");
//            throw new BusinessRuntimeException(ResultCodeEnum.CAN_NOT_LOGIN.getCode(), ResultCodeEnum.CAN_NOT_LOGIN.getMessage());
            return ResponseResult.failure(ResultCodeEnum.CAN_NOT_LOGIN.getCode(), ResultCodeEnum.CAN_NOT_LOGIN.getMessage());
        }

        Integer userId = (int) id;

        User user = userService.getUserInfoByUserId(userId);


        ProfileEntity entity = new ProfileEntity();

        Map<String, Object> map = new HashMap<>();
        Set<String> menus = new HashSet<>();
        Set<String> points = new HashSet<>();
        Set<String> tabPages = new HashSet<>();
        Department one = departmentService.findOne(user.getDeptId());

        entity.setMobile(user.getPhone());
        entity.setUsername(user.getUsername());
        if (!ObjectUtils.isEmpty(one)) {
            entity.setDeptName(one.getName());
        }

        Set<Role> roleListByUserId = userService.findRoleListByUserId(user.getId());
        List<Integer> roleIds = new ArrayList<>();
        entity.setRole(roleListByUserId);

        if (!CollectionUtils.isEmpty(roleListByUserId)) {
            for (Role role : roleListByUserId) {
                roleIds.add(role.getId());

                List<Permissions> permList = roleService.findPermListByRoleId(role.getId());
                if (!CollectionUtils.isEmpty(permList)) {
                    for (Permissions permissions : permList) {
                        if (MENU_PER.equals(permissions.getType())) {
                            menus.add(permissions.getCode());

                        } else if (POINT_PER.equals(permissions.getType())) {
                            points.add(permissions.getCode());
                        }else if (TAB_PER.equals(permissions.getType())){
                            tabPages.add(permissions.getCode());
                        }
                    }
                }
            }
            map.put("menus", menus);
            map.put("points", points);
            map.put("tabPages",tabPages);
            entity.setPermissions(map);
        }
        return ResponseResult.ok(entity);
    }


    /**
     * 同步钉钉用户到系统
     *
     * @return
     */
    @RequestMapping(value = "sync_dd_user")
    public ResponseResult importDDUser() throws Exception {

        //1.获取token
        String accessToken = getAccessToken();
        logger.info("accessToken:{}", accessToken);
        //2.获取所有的部门
        List<Department> allDepertmentId = ddUserService.getAllDepertmentId(accessToken);
        for (Department department : allDepertmentId) {
            //3.1查询是否存在部门，存在则更新，不存在得添加
            int cnt = departmentService.countByDDId(department.getDdId());
            if (cnt == 0) {
                departmentService.addDept(department);
            } else {
                departmentService.update(department);
            }
        }

        Map<String, Object> param = new HashMap<>();

        System.out.println("所有的部门："+allDepertmentId);
        //3.有部门则同步部门下的用户
        if (!CollectionUtils.isEmpty(allDepertmentId)) {
            int n = 0;
            for (Department o : allDepertmentId) {

                System.out.println("第"+n+"次循环");
                //3.2获取部门员工userId集合
                List<String> userIds = ddUserService.getUserIds(accessToken, o.getDdId());

                //3.3因钉钉每次只能同步100条数据。所以需要进行分页同步
                long cycle = userIds.size() % 100 == 0?userIds.size() / 100:userIds.size()/100+1;
                for (int i = 0; i < cycle; i++) {
                    List<User> departmentUserDetail = ddUserService.getDepartmentUserDetail(accessToken, Long.parseLong(o.getDdId()),i+1L,100L);
                    for (User user1 : departmentUserDetail) {
                        //查询系统是否已经有该用户的信息，如果有，则进行更新，没有，则添加用户信息
                        param.put("userId", user1.getUserId());
                        PageResult<UserDTO> pageResult1 = userService.listUser(1, 1, param);
                        if (CollectionUtils.isEmpty(pageResult1.getRows())) {
                            userService.addUser(user1);

                        } else {
                            user1.setId(pageResult1.getRows().get(0).getId());

                            userService.updateUser(user1);
                        }

                        System.out.println("通讯路同步的钉钉用户"+user1);
                    }
                }

                //3.4获取钉钉花名册信息
                int count = userIds.size()%20 == 0? userIds.size() /20:userIds.size()/20+1;
                System.out.println("count :" +count);
                for (int i = 0; i < count; i++) {
                    String userIdStr = "";
                    if (i == count -1){
                        for (int j = i*20; j < userIds.size(); j++) {
                            userIdStr+=userIds.get(j)+",";
                        }
                    }else {
                        for (int j = i*20; j < i*20+20; j++) {
                            userIdStr+=userIds.get(j)+",";
                        }
                    }
                    String paramUserIds = userIdStr.substring(0,userIdStr.length()-1);
                    System.out.println("请求钉钉的花名册参数："+paramUserIds);
                    getSmartworkUserList(accessToken, param, paramUserIds);

                }
                n++;
            }
        }

        return ResponseResult.ok();
    }

    private void getSmartworkUserList(String accessToken, Map<String, Object> param, String paramUserIds) throws Exception {
        List<UserDTO> smartWorkUserList = ddUserService.getSmartWorkUserList(accessToken, paramUserIds);
        for (UserDTO userDTO : smartWorkUserList) {
            User user = new User();
            BeanUtils.copyProperties(userDTO,user);

            //查询系统是否已经有该用户的信息，如果有，则进行更新，没有，则添加用户信息
            param.put("userId", userDTO.getUserId());
            Edu edu = userDTO.getEdu();
            PageResult<UserDTO> pageResult1 = userService.listUser(1, 1, param);
            if (CollectionUtils.isEmpty(pageResult1.getRows())) {
                userService.addUser(user);

                if (!StringUtils.isEmpty(edu.getSchool())||!StringUtils.isEmpty(edu.getMajor())){
                    eduMapper.insert(edu);
                    user.setEduId(edu.getId());
                }
            } else {
                UserDTO userDTO1 = pageResult1.getRows().get(0);
                user.setId(userDTO1.getId());
                Integer eduId = userDTO1.getEduId();
                if (!StringUtils.isEmpty(edu.getSchool())||!StringUtils.isEmpty(edu.getMajor())) {
                    if (!ObjectUtils.isEmpty(eduId)) {
                        edu.setId(eduId);
                        eduMapper.updateByPrimaryKeySelective(edu);
                    } else {

                        eduMapper.insert(edu);
                        user.setEduId(edu.getId());
                    }
                }

                userService.updateUser(user);
            }

            System.out.println("花名册定义的钉钉用户"+user);
        }
    }

    private String getAccessToken() throws Exception {
        String accessToken=null;
        Token token = tokenService.findToken();
        if(token.getDate()!=null&&token.getToken()!=null){
            if((new Date().getTime()-token.getDate().getTime())<=(105*60*1000)){
                accessToken=token.getToken();
            }else{
                accessToken = AuthHelper.getAccessToken(APP_KEY, APP_SECRET);
                tokenService.update(new Date(),accessToken);
            }
        }else{
            accessToken = AuthHelper.getAccessToken(APP_KEY, APP_SECRET);
            tokenService.update(new Date(),accessToken);
        }
        return accessToken;
    }

    @GetMapping("/syncUserDetail/{userId}")
    public ResponseResult syncUserDetail(@PathVariable("userId") String userId) throws Exception {
        //1.获取token
        String accessToken = getAccessToken();

        Map<String,Object> param = new HashMap<>();
        param.put("userId",userId);
        getSmartworkUserList(accessToken,param,userId);
        return ResponseResult.ok();
    }




    /*private Config getDTalkConfig() throws Exception {
        long curtime = System.currentTimeMillis();
        String nonceStr = RandomStringUtil.getRandomCode(10, 6);
        String url = SYSConfig.getProp().getProperty("auth_url");

        String accessToken = AuthHelper.getAccessToken(CORP_ID, CORP_SECRET);

        String jsapiTicket = AuthHelper.getJsapiTicket(accessToken);
        String sign = AuthHelper.sign(jsapiTicket, nonceStr, curtime, url);

        SYSConfig c = SYSConfig.getCurrentConfig();
        Config conf = new Config();
        conf.setAgentId(c.AGENT_ID);
        conf.setCorpId(c.CORP_ID);
        conf.setSign(sign);
        conf.setNonceStr(nonceStr);
        conf.setTimestamp(String.valueOf(curtime));
        conf.setAccessToken(accessToken);
        return conf;
    }*/
}
